package com.itianyu.blog.dao.implementations;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.itianyu.blog.dao.beans.Entry;
import com.itianyu.blog.dao.beans.Page;
import com.itianyu.blog.dao.beans.User;
import com.itianyu.blog.dao.interfaces.EntryInterface;

/**
 * 博文实现类
 * @author wumgji
 */
@Service
public class EntryImplementation implements EntryInterface {

	private static final long serialVersionUID = 1L;

	@PersistenceContext
	private EntityManager em;

	// 创建博文实体
	public Entry createEntry() {
		Entry entry = new Entry();
		return entry;
	}

	// 保存博文信息
	@Transactional
	public Entry saveEntry(Entry entry) {
		return em.merge(entry);
	}

	// 根据博文ID删除博文信息
	@Transactional
	public void deleteEntry(int entryId) {
		Entry entry = em.find(Entry.class, entryId);
		if (entry != null) {
			em.remove(entry);
		}
		return;
	}

	// 根据博文ID查询博文信息
	public Entry findEntry(int entryId) {
		return em.find(Entry.class, entryId);
	}

	// 根据发布状态查询博文列表
	@Transactional(readOnly = true)
	@SuppressWarnings("unchecked")
	public List<Entry> findEntryEntities(int page, int maxresults, boolean published) {
		int firstresult = (page - 1) * maxresults;

		Query q = em.createQuery("SELECT OBJECT(e) FROM Entry e WHERE e.published = :published ORDER BY e.creationDate DESC");
		q.setParameter("published", published);
		q.setMaxResults(maxresults);
		q.setFirstResult(firstresult);
		List<Entry> items = q.getResultList();

		return items;
	}

	// 根据发布状态计算博文列表的总数
	@Transactional(readOnly = true)
	public int getEntryEntitiesCount(boolean published) {
		Query q = em.createQuery("SELECT COUNT(e) FROM Entry e WHERE e.published = :published");
		q.setParameter("published", published);
		Long numresults = (Long) q.getSingleResult();
		return numresults.intValue();
	}

	// 根据标签查询已发布博文列表
	@Transactional(readOnly = true)
	@SuppressWarnings("unchecked")
	public List<Entry> findEntryEntitiesByTag(int page, int maxresults, int tagId) {
		int firstresult = (page - 1) * maxresults;

		Query q = em.createQuery("SELECT OBJECT(e) FROM Entry e JOIN e.tags t WHERE t.tagId = :tId and e.published = true ORDER BY e.creationDate DESC");
		q.setParameter("tId", tagId);
		q.setMaxResults(maxresults);
		q.setFirstResult(firstresult);
		List<Entry> items = q.getResultList();

		return items;
	}

	// 根据标签计算已发布博文列表的总数
	@Transactional(readOnly = true)
	public int getEntryEntitiesCountByTag(int tagId) {
		Query q = em.createQuery("SELECT COUNT(e) FROM Entry e JOIN e.tags t WHERE t.tagId = :tId and e.published = true");
		q.setParameter("tId", tagId);
		Long numresults = (Long) q.getSingleResult();
		return numresults.intValue();
	}

	// 查询已发布的归档博文列表
	@Transactional(readOnly = true)
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public List<String[]> findArchivesEntries() {
		// MySQL特有语法
		Query q = em.createNativeQuery("SELECT DISTINCT DATE_FORMAT(CREATION_DATE,'%Y'), DATE_FORMAT(CREATION_DATE,'%M'), DATE_FORMAT(CREATION_DATE,'%m') FROM ENTRY WHERE PUBLISHED = TRUE ORDER BY DATE_FORMAT(CREATION_DATE, '%Y') DESC,DATE_FORMAT(CREATION_DATE, '%m') desc");

		List<Object[]> tmpresult = q.getResultList();

		ArrayList result = new ArrayList();

		for (int i = 0; i < tmpresult.size(); i++) {

			String[] archive_entry = new String[4];

			Object[] archive_entry_tmp = tmpresult.get(i);

			// MySQL特有语法
			q = em.createNativeQuery("SELECT COUNT(*) FROM ENTRY WHERE DATE_FORMAT(CREATION_DATE,'%Y') = ? AND DATE_FORMAT(CREATION_DATE,'%M') = ? AND PUBLISHED = TRUE");

			q.setParameter(1, (String) archive_entry_tmp[0]);
			q.setParameter(2, (String) archive_entry_tmp[1]);

			archive_entry[0] = (String) archive_entry_tmp[0];
			archive_entry[1] = (String) archive_entry_tmp[1];
			// 截取月名称的前3个字符
			archive_entry[1] = archive_entry[1].substring(0, 3);
			archive_entry[2] = (String) archive_entry_tmp[2];

			Long num_entries = (Long) q.getSingleResult();
			archive_entry[3] = num_entries.toString();

			result.add(archive_entry);

		}

		return result;
	}

	// 根据日期查询已发布博文列表
	@Transactional(readOnly = true)
	@SuppressWarnings("unchecked")
	public List<Entry> findEntryEntitiesByDate(int page, int maxresults, int year, int month) {
		Calendar cal = Calendar.getInstance();
		Date startDate = null;
		Date endDate = null;

		// 如果月参数有效，查询对应博文；否则查询一年全部博文
		if (month >= 1 && month <= 12) {
			// 月参数从0到11，日参数从1到31
			cal.set(year, (month - 1), 1, 0, 0, 0);
			startDate = cal.getTime();
			cal.add(Calendar.MONTH, 1);
			cal.add(Calendar.DATE, -1);
			cal.set(Calendar.HOUR_OF_DAY, 23);
			cal.set(Calendar.MINUTE, 59);
			cal.set(Calendar.SECOND, 59);
			endDate = cal.getTime();
		} else {
			cal.set(year, Calendar.JANUARY, 1, 0, 0, 0);
			startDate = cal.getTime();
			cal.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
			endDate = cal.getTime();
		}

		int firstresult = (page - 1) * maxresults;

		Query q = em.createQuery("SELECT OBJECT(e) FROM Entry e WHERE e.creationDate >= :startDate and e.creationDate <= :endDate and e.published = true ORDER BY e.creationDate DESC");
		q.setParameter("startDate", startDate);
		q.setParameter("endDate", endDate);
		q.setMaxResults(maxresults);
		q.setFirstResult(firstresult);
		List<Entry> items = q.getResultList();

		return items;
	}

	// 根据日期计算已发布博文列表的总数
	@Transactional(readOnly = true)
	public int getEntryEntitiesCountByDate(int year, int month) {
		Calendar cal = Calendar.getInstance();
		Date startDate = null;
		Date endDate = null;

		// 如果月参数有效，查询对应博文；否则查询一年全部博文
		if (month >= 1 && month <= 12) {
			// 月参数从0到11，日参数从1到31
			cal.set(year, (month - 1), 1, 0, 0, 0);
			startDate = cal.getTime();
			cal.add(Calendar.MONTH, 1);
			cal.add(Calendar.DATE, -1);
			cal.set(Calendar.HOUR_OF_DAY, 23);
			cal.set(Calendar.MINUTE, 59);
			cal.set(Calendar.SECOND, 59);
			endDate = cal.getTime();
		} else {
			cal.set(year, Calendar.JANUARY, 1, 0, 0, 0);
			startDate = cal.getTime();
			cal.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
			endDate = cal.getTime();
		}

		Query q = em.createQuery("SELECT COUNT(e) FROM Entry e WHERE e.published = true and e.creationDate >= :startDate and e.creationDate <= :endDate");
		q.setParameter("startDate", startDate);
		q.setParameter("endDate", endDate);
		Long num_results = (Long) q.getSingleResult();

		return num_results.intValue();
	}

	@Override
	public List<Entry> findEntryPageEntities(User user) {
		String userName1=user.getUsername();
		String str="";
		if(userName1.equals("admin")){
			str="SELECT OBJECT(p) FROM Entry p ORDER BY p.entryId ASC";
		}else{
			str="SELECT OBJECT(p) FROM Entry p where p.userName1 = '"+userName1+"' ORDER BY p.entryId ASC";
		}
		Query q = em.createQuery(str);
		List<Entry> items = q.getResultList();
		return items;
	}

}
